home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / main / sun4c.md / mainInit.c < prev    next >
C/C++ Source or Header  |  1991-04-21  |  12KB  |  468 lines

  1. /* 
  2.  *  main.c --
  3.  *
  4.  *    The main program for Sprite: initializes modules and creates
  5.  *    system processes. Also creates a process to run the Init program.
  6.  *
  7.  * Copyright 1986 Regents of the University of California
  8.  * All rights reserved.
  9.  */
  10.  
  11. #ifndef lint
  12. static char rcsid[] = "$Header: /sprite/src/kernel/main/sun4.md/RCS/mainInit.c,v 9.7 90/10/19 15:39:17 shirriff Exp Locker: mgbaker $ SPRITE (Berkeley)";
  13. #endif /* !lint */
  14.  
  15. #include <sprite.h>
  16. #include <dbg.h>
  17. #include <dev.h>
  18. #include <net.h>
  19. #include <fs.h>
  20. #include <fsutil.h>
  21. #include <proc.h>
  22. #include <prof.h>
  23. #include <recov.h>
  24. #include <rpc.h>
  25. #include <sched.h>
  26. #include <sig.h>
  27. #include <sync.h>
  28. #include <sys.h>
  29. #include <timer.h>
  30. #include <vm.h>
  31. #include <machMon.h>
  32. #include <devAddrs.h>
  33. #include <mach.h>
  34. #include <stdlib.h>
  35. #include <main.h>
  36. #include <stdio.h>
  37. #include <bstring.h>
  38. #include <string.h>
  39. #include <dump.h>
  40.  
  41. static void Init _ARGS_((void));
  42.  
  43. /*
  44.  *  Pathname of the Init program.
  45.  */
  46. #define INIT         "cmds/initsprite"
  47.  
  48. int main_PrintInitRoutines = FALSE;/* print out each routine as it's called. */
  49.  
  50. int main_PanicOK = 0;    /* Set to 1 if it's OK to panic. */
  51.  
  52. /*
  53.  *----------------------------------------------------------------------
  54.  *
  55.  * main --
  56.  *
  57.  *    All kernel modules are initialized by calling their *_Init()
  58.  *    routines. In addition, kernel processes are created to
  59.  *    handle virtual memory and rpc-specific stuff. The last process
  60.  *    created runs the `init' program.
  61.  *
  62.  * Results:
  63.  *    None.
  64.  *
  65.  * Side effects:
  66.  *    The whole system is initialized.
  67.  *
  68.  *----------------------------------------------------------------------
  69.  */
  70.  
  71. void
  72. main()
  73. {
  74.     Proc_PID    pid;
  75.     int        i;
  76.  
  77.     /*
  78.      * Initialize variables specific to a given kernel.  
  79.      * IMPORTANT: Only variable assignments and nothing else can be
  80.      *          done in this routine.
  81.      */
  82.     Main_InitVars();
  83.  
  84.     /*
  85.      * Initialize machine dependent info.  MUST BE CALLED HERE!!!.
  86.      */
  87.     Mach_Init();
  88.  
  89.     /*
  90.      * Initialize the debugger.
  91.      */
  92.     Dbg_Init();
  93.  
  94.     /*
  95.      * Initialize the system module, particularly the fact that there is an
  96.      * implicit DISABLE_INTR on every processor.
  97.      */
  98.     if (main_PrintInitRoutines) {
  99.     Mach_MonPrintf("Calling Sys_Init().\n");
  100.     }
  101.     Sys_Init();
  102.  
  103.     /*
  104.      * Now allow memory to be allocated by the "Vm_BootAlloc" call.  Memory
  105.      * can be allocated by this method until "Vm_Init" is called.  After this
  106.      * then the normal memory allocator must be used.
  107.      */
  108.     if (main_PrintInitRoutines) {
  109.     Mach_MonPrintf("Calling Vm_BootInit().\n");
  110.     }
  111.     Vm_BootInit();
  112.  
  113.     /*
  114.      * Initialize all devices.
  115.      */
  116.     if (main_PrintInitRoutines) {
  117.     Mach_MonPrintf("Calling Dev_Init().\n");
  118.     }
  119.     Dev_Init();
  120.  
  121.     /*
  122.      *  Initialize the mappings of keys to call dump routines.
  123.      *  Must be after Dev_Init. 
  124.      */
  125.     if (main_DoDumpInit) {
  126.     if (main_PrintInitRoutines) {
  127.         Mach_MonPrintf("Calling Dump_Init().\n");
  128.     }
  129.     Dump_Init();
  130.     }
  131.  
  132.     /*
  133.      * Initialize the timer, signal, process, scheduling and synchronization
  134.      * modules' data structures.
  135.      */
  136.     if (main_PrintInitRoutines) {
  137.     Mach_MonPrintf("Calling Proc_Init().\n");
  138.     }
  139.     Proc_Init();
  140.     if (main_PrintInitRoutines) {
  141.     Mach_MonPrintf("Calling Sync_LockStatInit().\n");
  142.     }
  143.     Sync_LockStatInit();
  144.     if (main_PrintInitRoutines) {
  145.     Mach_MonPrintf("Calling Timer_Init().\n");
  146.     }
  147.     Timer_Init();
  148.     if (main_PrintInitRoutines) {
  149.     Mach_MonPrintf("Calling Sig_Init().\n");
  150.     }
  151.     Sig_Init();
  152.     if (main_PrintInitRoutines) {
  153.     Mach_MonPrintf("Calling Sched_Init().\n");
  154.     }
  155.     Sched_Init();
  156.     if (main_PrintInitRoutines) {
  157.     Mach_MonPrintf("Calling Sync_Init().\n");
  158.     }
  159.     Sync_Init();
  160.  
  161.     /*
  162.      * Sys_Printfs are not allowed before this point.
  163.      */  
  164.     main_PanicOK++;
  165.     printf("Sprite kernel: %s\n", SpriteVersion());
  166.  
  167.     /*
  168.      * Set up bins for the memory allocator.
  169.      */
  170.     if (main_PrintInitRoutines) {
  171.     Mach_MonPrintf("Calling Fs_Bin\n");
  172.     }
  173.     Fs_Bin();
  174.     if (main_PrintInitRoutines) {
  175.     Mach_MonPrintf("Calling Net_Bin\n");
  176.     }
  177.     Net_Bin();
  178.  
  179.     /*
  180.      * Initialize virtual memory.  After this point must use the normal
  181.      * memory allocator to allocate memory.  If you use Vm_BootAlloc then
  182.      * will get a panic into the debugger.
  183.      */
  184.     if (main_PrintInitRoutines) {
  185.     Mach_MonPrintf("Calling Vm_Init\n");
  186.     }
  187.     Vm_Init();
  188.  
  189.     /*
  190.      * malloc can be called from this point on.
  191.      */
  192.  
  193.     /*
  194.      * Initialize the main process. Must be called before any new 
  195.      * processes are created.
  196.      * Dependencies: Proc_InitTable, Sched_Init, Vm_Init, Mem_Init
  197.      */
  198.     if (main_PrintInitRoutines) {
  199.     Mach_MonPrintf("Calling Proc_InitMainProc\n");
  200.     }
  201.     Proc_InitMainProc();
  202.  
  203.     /*
  204.      * Initialize the network and the routes.  It would be nice if we
  205.      * could call Net_Init earlier so that we can use the debugger earlier
  206.      * but we must call Vm_Init first.  VM could be changed so that we
  207.      * could move the call earlier however.
  208.      */
  209.     if (main_PrintInitRoutines) {
  210.     Mach_MonPrintf("Calling Net_Init\n");
  211.     }
  212.     Net_Init();
  213.     if (main_PrintInitRoutines) {
  214.     Mach_MonPrintf("Calling Net_RouteInit\n");
  215.     }
  216.     Net_RouteInit();
  217.  
  218.     /*
  219.      * Enable server process manager.
  220.      */
  221.     if (main_PrintInitRoutines) {
  222.     Mach_MonPrintf("Calling Proc_ServerInit\n");
  223.     }
  224.     Proc_ServerInit();
  225.  
  226.     /*
  227.      * Initialize the recovery module.  Do before Rpc and after Vm_Init.
  228.      */
  229.     if (main_PrintInitRoutines) {
  230.     Mach_MonPrintf("Calling Recov_Init\n");
  231.     }
  232.     Recov_Init();
  233.  
  234.     /*
  235.      * Initialize the data structures for the Rpc system.  This uses
  236.      * Vm_RawAlloc to so it must be called after Vm_Init.
  237.      * Dependencies: Timer_Init, Vm_Init, Net_Init, Recov_Init
  238.      */
  239.     if (main_PrintInitRoutines) {
  240.     Mach_MonPrintf("Calling Rpc_Init\n");
  241.     }
  242.     Rpc_Init();
  243.  
  244.     /*
  245.      * Configure devices that may or may not exist.  This needs to be
  246.      * done after Proc_InitMainProc because the initialization routines
  247.      * use SetJump which uses the proc table entry for the main process.
  248.      */
  249.     if (main_PrintInitRoutines) {
  250.     Mach_MonPrintf("Calling Dev_Config\n");
  251.     }
  252.     Dev_Config();
  253.  
  254.     /*
  255.      * Initialize profiling after the timer and vm stuff is set up.
  256.      * Dependencies: Timer_Init, Vm_Init
  257.      */
  258.     if (main_DoProf) {
  259.     Prof_Init();
  260.     }
  261.     /*
  262.      *  Allow interrupts from now on.
  263.      */
  264.     if (main_PrintInitRoutines) {
  265.     Mach_MonPrintf("Enabling interrupts\n");
  266.     }
  267.     Mach_MonStartNmi();
  268.     ENABLE_INTR();
  269.  
  270.     if (main_Debug) {
  271.     DBG_CALL;
  272.     }
  273.  
  274.     /*
  275.      * Sleep for a few seconds to calibrate the idle time ticks.
  276.      */
  277.     Sched_TimeTicks();
  278.  
  279.     /*
  280.      * Start profiling, if desired.
  281.      */
  282.     if (main_DoProf) {
  283.         (void) Prof_Start();
  284.     }
  285.  
  286.     /*
  287.      * Do an initial RPC to get a boot timestamp.  This allows
  288.      * servers to detect when we crash and reboot.  This will set the
  289.      * system clock too, although rdate is usually done from user level later.
  290.      */
  291.     if (main_PrintInitRoutines) {
  292.     Mach_MonPrintf("Call Rpc_Start\n");
  293.     }
  294.     Rpc_Start();
  295.  
  296.     /*
  297.      * Initialize the file system. 
  298.      */
  299.     if (main_PrintInitRoutines) {
  300.     Mach_MonPrintf("Call Fs_Init\n");
  301.     }
  302.     Fs_Init();
  303.  
  304.     /*
  305.      * Before starting up any more processes get a current directory
  306.      * for the main process.  Subsequent new procs will inherit it.
  307.      */
  308.     if (main_PrintInitRoutines) {
  309.     Mach_MonPrintf("Call Fs_ProcInit\n");
  310.     }
  311.     Fs_ProcInit();
  312.     if (main_PrintInitRoutines) {
  313.     Mach_MonPrintf("Bunch of call funcs\n");
  314.     }
  315.     /*
  316.      * Start the clock daemon and the routine that opens up the swap directory.
  317.      */
  318.     Proc_CallFunc(Vm_Clock, (ClientData) NIL, 0);
  319.     Proc_CallFunc(Vm_OpenSwapDirectory, (ClientData) NIL, 0);
  320.  
  321.     /*
  322.      * Start the process that synchronizes the filesystem caches
  323.      * with the data kept on disk.
  324.      */
  325.     Proc_CallFunc(Fsutil_SyncProc, (ClientData) NIL, 0);
  326.  
  327.     /*
  328.      * Create a few RPC server processes and the Rpc_Daemon process which
  329.      * will create more server processes if needed.
  330.      */
  331.     if (main_NumRpcServers > 0) {
  332.     for (i=0 ; i<main_NumRpcServers ; i++) {
  333.         (void) Rpc_CreateServer((int *) &pid);
  334.     }
  335.     }
  336.     (void) Proc_NewProc((Address) Rpc_Daemon, PROC_KERNEL, FALSE, &pid,
  337.     "Rpc_Daemon");
  338.     if (main_PrintInitRoutines) {
  339.     Mach_MonPrintf("Creating Proc server procs\n");
  340.     }
  341.  
  342.     /*
  343.      * Create processes  to execute functions.
  344.      */
  345.     for (i = 0; i < proc_NumServers; i++) {
  346.     (void) Proc_NewProc((Address) Proc_ServerProc, PROC_KERNEL, FALSE, 
  347.             &pid, "Proc_ServerProc");
  348.     }
  349.  
  350.     /*
  351.      * Create a recovery process to monitor other hosts.  Can't use
  352.      * Proc_CallFunc's to do this because they can be used up waiting
  353.      * for page faults against down servers.  (Alternatively the VM
  354.      * code could be fixed up to retry page faults later instead of
  355.      * letting the Proc_ServerProc wait for recovery.)
  356.      */
  357.     (void) Proc_NewProc((Address) Recov_Proc, PROC_KERNEL, FALSE, &pid,
  358.             "Recov_Proc");
  359.     /*
  360.      * Set up process migration recovery management.
  361.      */
  362.     if (main_PrintInitRoutines) {
  363.     Mach_MonPrintf("Calling Proc_MigInit\n");
  364.     }
  365.     Proc_MigInit();
  366.  
  367.     /*
  368.      * Call the routine to start test kernel processes.
  369.      */
  370.  
  371.     if (main_PrintInitRoutines) {
  372.     Mach_MonPrintf("Calling Main_HookRoutine\n");
  373.     }
  374.     Main_HookRoutine();
  375.  
  376.     /*
  377.      * Print out the amount of memory used.
  378.      */
  379.     printf("MEMORY %d bytes allocated for kernel\n", 
  380.         vmMemEnd - mach_KernStart);
  381.     /*
  382.      * Start up the first user process.
  383.      */
  384.     if (main_PrintInitRoutines) {
  385.     Mach_MonPrintf("Creating Init\n");
  386.     }
  387.     (void) Proc_NewProc((Address) Init, PROC_KERNEL, FALSE, &pid, "Init");
  388.  
  389.     (void) Sync_WaitTime(time_OneYear);
  390.     printf("Main exiting\n");
  391.     Proc_Exit(0);
  392. }
  393.  
  394.  
  395. /*
  396.  *----------------------------------------------------------------------
  397.  *
  398.  * Init --
  399.  *
  400.  *    This routine execs the init program.
  401.  *
  402.  * Results:
  403.  *    This routine only returns an error if the exec failed.
  404.  *
  405.  * Side effects:
  406.  *    The current process image is overlayed by the init process.
  407.  *
  408.  *----------------------------------------------------------------------
  409.  */
  410. static void
  411. Init()
  412. {
  413.     char        *initArgs[10];
  414.     ReturnStatus    status;
  415.     char        argBuffer[100];
  416.     int            argc;
  417.     Fs_Stream        *dummy;
  418.     char        bootCommand[103];
  419.     char        *ptr;
  420.     int            i;
  421.     int            argLength;
  422.  
  423.     if (main_PrintInitRoutines) {
  424.     Mach_MonPrintf("In Init\n");
  425.     }
  426.     bzero(bootCommand, 103);
  427.     argc = Mach_GetBootArgs(8, 100, &(initArgs[2]), argBuffer);
  428.     if (argc > 0) {
  429.     argLength = (((int) initArgs[argc+1]) + strlen(initArgs[argc+1]) +
  430.             1 - ((int) argBuffer));
  431.     } else {
  432.     argLength = 0;
  433.     }
  434.     if (argLength > 0) {
  435.     initArgs[1] = "-b";
  436.     ptr = bootCommand;
  437.     for (i = 0; i < argLength; i++) {
  438.         if (argBuffer[i] == '\0') {
  439.         *ptr++ = ' ';
  440.         } else {
  441.         *ptr++ = argBuffer[i];
  442.         }
  443.     }
  444.     bootCommand[argLength] = '\0';
  445.     initArgs[2] = bootCommand;
  446.     initArgs[argc + 2] = (char *) NIL;
  447.     } else {
  448.     initArgs[1] = (char *) NIL;
  449.     }
  450.     if (main_AltInit != 0) {
  451.     initArgs[0] = main_AltInit;
  452.     printf("Execing \"%s\"\n", initArgs[0]);
  453.     status = Proc_KernExec(initArgs[0], initArgs);
  454.     printf( "Init: Could not exec %s status %x.\n",
  455.             initArgs[0], status);
  456.     }
  457.     status = Fs_Open(INIT,FS_EXECUTE | FS_FOLLOW, FS_FILE, 0, &dummy);
  458.     if (status != SUCCESS) {
  459.     printf("Can't open %s <0x%x>\n", INIT,status);
  460.     }
  461.     initArgs[0] = INIT;
  462.     status = Proc_KernExec(initArgs[0], initArgs);
  463.     printf( "Init: Could not exec %s status %x.\n",
  464.             initArgs[0], status);
  465.     Proc_Exit(1);
  466. }
  467.  
  468.